import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

//测试类注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@interface Extra {
    int age() default 0;

    String gender() default "male";
}

//测试属性注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface FieldTestAnn {
    String field();
}

//测试方法注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MethodTestAnn {
    String method();
}

@Extra(age = 1, gender = "female")
class ExtraPerson {

    @FieldTestAnn(field = "nameAnn")
    String name;

    @MethodTestAnn(method = "runAnn")
    public void run() {}

    public void eat(String food) {
        System.out.println("I'm eating " + food);
    }

}


public class AnnFieldTest {

    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        //获取注解的属性
        Class<ExtraPerson> extraPersonClass = ExtraPerson.class;
        Annotation[] annotations = extraPersonClass.getAnnotations();
        System.out.println(Arrays.asList(annotations));//@Extra(gender=female, age=1)]

        Extra declaredAnnotation = extraPersonClass.getDeclaredAnnotation(Extra.class);
        System.out.println("age:" + declaredAnnotation.age() + ", gender:" + declaredAnnotation.gender());

        //获取属性的注解属性
        Field name = extraPersonClass.getDeclaredField("name");
        if (name.isAnnotationPresent(FieldTestAnn.class)) {
            System.out.println("属性的注解属性:" + name.getDeclaredAnnotation(FieldTestAnn.class).field());
        }

        //获取方法的注解属性
        Method run = extraPersonClass.getDeclaredMethod("run");
        if (run.isAnnotationPresent(MethodTestAnn.class)) {
            System.out.println("方法的注解属性:" + run.getDeclaredAnnotation(MethodTestAnn.class).method());
        }

        Method[] methods = extraPersonClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("method:" + method);
            System.out.println("method's class" + method.getDeclaringClass());
            Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length>0) {
                System.out.println("P:" + parameterTypes[0]);
            }
        }
    }
}
